/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.atomojo.app.storage.xmldb;

import java.io.IOException;
import java.io.Reader;
import java.net.URI;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.atomojo.app.AtomResource;
import org.atomojo.app.db.Entry;
import org.infoset.xml.Attribute;
import org.infoset.xml.DocumentLoader;
import org.infoset.xml.Element;
import org.infoset.xml.InfosetFactory;
import org.infoset.xml.Item;
import org.infoset.xml.ItemConstructor;
import org.infoset.xml.ItemDestination;
import org.infoset.xml.XMLException;
import org.infoset.xml.filter.ItemFilter;
import org.infoset.xml.filter.RemoveDocumentFilter;
import org.restlet.Client;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.Method;
import org.restlet.data.Reference;
import org.restlet.representation.Representation;

/**
 *
 * @author alex
 */
public class FeedLoader {
   
   DocumentLoader loader;
   Representation feedRep;
   Logger log;
   Iterator<Entry> entries;
   public FeedLoader(Logger log,DocumentLoader loader,Representation feedRep,Iterator<Entry> entries)
   {
      this.log = log;
      this.feedRep = feedRep;
      this.loader = loader;
      this.entries = entries;
   }
   
   public void load(final XMLDBStorage storage,final Client client,final String path,final ItemDestination dest)
      throws IOException,XMLException
   {
      Reader r = feedRep.getReader();
      loader.generate(r, new ItemDestination() {
         ItemConstructor constructor = InfosetFactory.getDefaultInfoset().createItemConstructor();
         URI baseURI;
         int level = 0;
         public void send(Item item)
            throws XMLException
         {
            switch (item.getType()) {
               case ElementItem:
                  if (level==0) {
                     baseURI = ((Element)item).getBaseURI();
                     ((Element)item).addNamespaceBinding("app", AtomResource.APP_NAMESPACE);
                  }
                  level++;
                  break;
               case ElementEndItem:
                  level--;
                  if (level==0) {
                     while (entries.hasNext()) {
                        Entry entry = entries.next();
                        Reference entryRef = storage.makeEntryReference(path, entry.getUUID());
                        dest.send(constructor.createCharacters("\n"));
                        Response response = client.handle(new Request(Method.GET,entryRef));
                        if (response.getStatus().isSuccess()) {
                           try {
                              Reader r = response.getEntity().getReader();
                              loader.generate(r, 
                                 new RemoveDocumentFilter(
                                    new ItemFilter() {
                                       boolean started = false;
                                       public void send(Item item) 
                                          throws XMLException
                                       {
                                          /*
                                          if (!started && item.getType()==Item.ItemType.ElementItem) {
                                             ((Element)item).setBaseURI(baseURI);
                                          }
                                           */
                                          if (item.getType()==Item.ItemType.ElementItem) {
                                             // clear base URI
                                             ((Element)item).setBaseURI(null);
                                             ((Element)item).getAttributes().remove(Attribute.XML_BASE);
                                          }
                                          dest.send(item);
                                       }
                                       public void attach(ItemDestination dest) {
                                       }
                                    }
                                 )
                              );
                              r.close();
                           } catch (Exception ex) {
                              log.log(Level.SEVERE,"Cannot parse entry document "+entryRef,ex);
                           }
                           response.getEntity().release();
                        } else {
                           log.log(Level.SEVERE,"Cannot open entry document "+entryRef+" due to status="+response.getStatus().getCode());
                        }
                        
                     }
                     dest.send(constructor.createCharacters("\n"));
                  }
                  break;
            }
            dest.send(item);
         }
      });
      r.close();
   }

}
